// import WebSocket from 'ws';

export class WebSocketClient {
    url: string;
    reconnectDelay: number;
    heartbeatInterval: number;
    heartbeatMsg: string;
    socket: WebSocket|null;
    isConnected: boolean;
    heartbeatTimer: number | null;
    reconnectTimer: number | null;
    private messageHandler: ((data: any) => void) | null;
    private heartbeatTimeoutTimer: number | null = null;
    private heartbeatTimeout: number;
    private allReconnect:boolean = true;
    private idleCount = 0;
    constructor(url: string, options: {
        reconnectDelay?: number;
        heartbeatInterval?: number;
        heartbeatMsg?: string;
        heartbeatTimeout?: number;
        onMessage?: (data: any) => void;
    } = {}) {
        this.url = url;
        this.reconnectDelay = options.reconnectDelay || 5000; // 重连间隔时间
        this.heartbeatInterval = options.heartbeatInterval || 3000; // 心跳间隔时间
        this.heartbeatMsg = options.heartbeatMsg || 'xxpingxx'; // 心跳消息
        this.socket = null;
        this.isConnected = false;
        this.allReconnect = true;
        this.heartbeatTimer = null;
        this.reconnectTimer = null;
        this.messageHandler = options.onMessage || null;
        this.heartbeatTimeout = options.heartbeatTimeout || 3000; // 心跳超时时间
    }

    // 连接WebSocket
    connect(onOpen?: () => void) {
        // 创建WebSocket对象
        this.socket = new WebSocket(this.url);
        // 监听WebSocket连接打开事件
        this.socket?.addEventListener('open', () => {
            // 设置连接状态为已连接
            this.isConnected = true;
            // 打印连接成功信息
            console.log('WebSocket connection established');
            // 启动心跳检测
            this.startHeartbeat();
            if (onOpen) {
                onOpen()
            }
        });
        // 监听WebSocket接收消息事件
        this.socket?.addEventListener('message', (event) => {
            // 如果接收到的消息是心跳响应
            console.log('Message received data:', event.data);
            if (event.data.toString() === 'xxpongxx') {
                // 清除超时计时器
                if (this.heartbeatTimeoutTimer) {
                    clearTimeout(this.heartbeatTimeoutTimer);
                    this.heartbeatTimeoutTimer = null;
                }
                console.log('Heartbeat response received:', event.data);
                this.idleCount +=1;
                if (this.idleCount > 7000) {
                    console.log('idleCount reached max close socket. idleCount:', this.idleCount);
                    this.close();
                }
                console.log('idleCount:', this.idleCount);
                return;
            } else if(event.data.toString() ==='xxclosexx') {
                console.log("recv close ws")
                this.close()
                return
            }
            
            if (this.messageHandler) {
                this.idleCount = 0;
                if (event.data instanceof ArrayBuffer) {
                    const uint8Array = new Uint8Array(event.data);
                    this.messageHandler(uint8Array);
                } else if (event.data instanceof Uint8Array) {
                    this.messageHandler(event.data.buffer);
                } else if (event.data instanceof Blob) {
                    // 创建 FileReader 对象
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        const arrayBuffer = e.target?.result;
                        if (arrayBuffer instanceof ArrayBuffer) {
                            const uint8Array = new Uint8Array(arrayBuffer);
                            if (this.messageHandler) {
                                this.messageHandler(uint8Array);
                            }
                        } else {
                            console.error('Failed to read Blob as ArrayBuffer');
                        }
                    };
                    // 读取 Blob 为 ArrayBuffer
                    reader.readAsArrayBuffer(event.data);
                }else {
                    console.error('Received data data type:', typeof event.data);
                }
                // 调用消息处理函数
            }            
        });

        this.socket?.addEventListener('close', () => {
            this.isConnected = false;
            console.log('WebSocket connection closed');
            this.stopHeartbeat();
            this.reconnect();
        });
        this.socket?.addEventListener('error', (errorEvent) => {
            console.error('WebSocket error:', errorEvent);
            if (this.socket) {
                this.socket.close();
            }
        });
    }

    send(message: string | Uint8Array) {
        console.log('send ws message:', message);
        if (message !== this.heartbeatMsg) {
            this.idleCount = 0;
        }
        
        if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {
            this.socket.send(message);
        } else {
            console.error('WebSocket is not connected');
        }
    }

    startHeartbeat() {
        this.stopHeartbeat();
        this.heartbeatTimer = window.setInterval(() => {
            if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {
                try {
                    this.send(this.heartbeatMsg);
                    // 设置心跳超时计时器
                    if (this.heartbeatTimeoutTimer) {
                        clearTimeout(this.heartbeatTimeoutTimer);
                    }
                    this.heartbeatTimeoutTimer = window.setTimeout(() => {
                        console.log('Heartbeat timeout, reconnecting...');
                        if (this.socket) {
                            this.socket.close();
                            this.socket = null;
                        }
                        this.isConnected = false;
                        this.reconnect();
                    }, this.heartbeatTimeout);
                } catch (error) {
                    console.error('Failed to send heartbeat:', error);
                    this.socket?.close();
                }
            }
        }, this.heartbeatInterval);
    }

    stopHeartbeat() {
        if (this.heartbeatTimer) {
            window.clearInterval(this.heartbeatTimer);
            this.heartbeatTimer = null;
        }
        if (this.heartbeatTimeoutTimer) {
            window.clearTimeout(this.heartbeatTimeoutTimer);
            this.heartbeatTimeoutTimer = null;
        }
    }

    reconnect() {
        if (!this.isConnected && this.allReconnect) {
            console.log(`Reconnecting in ${this.reconnectDelay / 1000} seconds...`);
            this.reconnectTimer = window.setTimeout(() => {
                this.connect();
            }, this.reconnectDelay);
        }
    }

    close() {
        console.log('close ws');
        this.allReconnect = false;
        this.stopHeartbeat();
        if (this.reconnectTimer) {
            window.clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
        if (this.socket?.readyState === WebSocket.OPEN) {
            this.socket.close();
            this.socket = null;
        }
    }

    connected() {
        this.socket?.readyState
        return this.isConnected;
    }

    status() {
        return this.socket?.readyState;
    }
}
